package com.jason.core.wilddog.util;

import com.jason.core.wilddog.handler.AbstractTransactionHandler;
import com.jason.core.wilddog.listener.CompletionListenerLogger;
import com.wilddog.client.Logger;
import com.wilddog.client.SyncReference;
import com.wilddog.client.WilddogSync;
import com.wilddog.wilddogcore.WilddogApp;
import com.wilddog.wilddogcore.WilddogOptions;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;
import java.util.Objects;

/**
 * @author he peng
 * @create 2017/12/15 14:26
 * @see
 */
public class WilddogSyncUtils {

    private static volatile WilddogSync WILD_DOG_SYNC_INSTANCE;

    private WilddogSyncUtils() {}

    /**
     * 根据 appId 获取 {@link WilddogSync} 的实例
     * @param appId
     * @param level
     * @return
     */
    public static final WilddogSync getWilddogSyncInstance(String appId , Logger.Level level) {
        if (StringUtils.isBlank(appId)) {
            throw new IllegalArgumentException("appId must not blank");
        }
        if (Objects.isNull(WILD_DOG_SYNC_INSTANCE)) {
            synchronized (WilddogSyncUtils.class) {
                if (Objects.isNull(WILD_DOG_SYNC_INSTANCE)) {
                    WilddogOptions options = new WilddogOptions.Builder()
                            .setSyncUrl("https://" + appId + ".wilddogio.com").build();
                    WilddogApp.initializeApp(options);
                    WILD_DOG_SYNC_INSTANCE = WilddogSync.getInstance();
                }
            }
        }
        WILD_DOG_SYNC_INSTANCE.setLogLevel(level);
        return WILD_DOG_SYNC_INSTANCE;
    }

    public static final void addNode(Object node , Object priority , CompletionListenerLogger listener) {
        SyncReference rootRef = WILD_DOG_SYNC_INSTANCE.getReference();
        rootRef.setValue(node , priority , listener);
    }

    public static final void addNode(
                String path , Object node , Object priority , CompletionListenerLogger listener) {
        if (StringUtils.isBlank(path)) {
            throw new IllegalArgumentException("path must not blank");
        }
        SyncReference ref = WILD_DOG_SYNC_INSTANCE.getReference(path);
        ref.setValue(node , priority , listener);
    }

    public static final void appendNode(Object node , Object priority , CompletionListenerLogger listener) {
        SyncReference rootRef = WILD_DOG_SYNC_INSTANCE.getReference();
        rootRef.push().setValue(node , priority , listener);
    }

    public static final void appendNode(
                String path , Object node , Object priority , CompletionListenerLogger listener) {
        if (StringUtils.isBlank(path)) {
            throw new IllegalArgumentException("path must not blank");
        }
        SyncReference ref = WILD_DOG_SYNC_INSTANCE.getReference(path);
        ref.push().setValue(node , priority , listener);
    }

    public static final void updateChildNode(String path , Map<String , Object> node , CompletionListenerLogger listener) {
        SyncReference ref = WILD_DOG_SYNC_INSTANCE.getReference(path);
        ref.updateChildren(node , listener);
    }

    public static final void removeNode(String path , CompletionListenerLogger listener) {
        if (StringUtils.isBlank(path)) {
            throw new IllegalArgumentException("path must not blank");
        }
        SyncReference ref = WILD_DOG_SYNC_INSTANCE.getReference(path);
        ref.removeValue(listener);
    }

    public static final void runTransaction(
                String path , Object node , AbstractTransactionHandler transactionHandler , boolean localEvents) {
        if (StringUtils.isBlank(path)) {
            throw new IllegalArgumentException("path must not blank");
        }
        transactionHandler.setData(node);
        SyncReference ref = WILD_DOG_SYNC_INSTANCE.getReference(path);
        ref.runTransaction(transactionHandler , localEvents);
    }

}
